
#include "hilbert.h"
#include <stdio.h>
#include <iostream.h>

void Pad (char *inString) {
	for (int i = 0; inString[i] == ' ' && inString[i] != 0; i++) {
		inString[i] = '0';
	}
}

void ConvertToString (char *output, int xCoord, int yCoord) {
	bitmask_t input[2];
	input[0] = xCoord;
	input[1] = yCoord;
	bitmask_t hilbert_result = hilbert_c2i(2, sizeof(int) * 8, input); 
	sprintf (output, "%21llu", hilbert_result);
	Pad (output);
}

void ConvertToCoords (char *input, int &xCoord, int &yCoord) {
	bitmask_t otherWay;
	bitmask_t output[2];
	sscanf (input, "%llu", &otherWay);
	hilbert_i2c(2, sizeof(int) * 8, otherWay, output);
	xCoord = output[0];
	yCoord = output[1];
}

// returns a zero if we are past the box
int GetBounds (char *lowPoint, char *highPoint, int xlow, int ylow, int xhigh, int yhigh) {
	unsigned low[2];
	unsigned high[2];

	low[0] = xlow;
	low[1] = ylow;
	high[0] = xhigh;
	high[1] = yhigh;
	hilbert_box_pt (2, sizeof (int), 8 * sizeof (int), 1, low, high);
	ConvertToString (lowPoint, low[0], low[1]);

	low[0] = xlow;
	low[1] = ylow;
	high[0] = xhigh;
	high[1] = yhigh;
	hilbert_box_pt (2, sizeof (int), 8 * sizeof (int), 0, low, high);
	ConvertToString (highPoint, low[0], low[1]);
}


int main () {

	int xcoord, ycoord;

	cout << "Please input your two integers to transform: \n";
	cin >> xcoord;
	cin >> ycoord;

	// now we take those two inputs and transform them into a string in Hilbert space
	char myString[100];
	ConvertToString (myString, xcoord, ycoord);
	cout << "Here are your two coords in Hilbert space as a string that you can index: " << myString << "\n";	

	// now we take that string and transform it back into two coordinates
	xcoord = ycoord = -1;
	ConvertToCoords (myString, xcoord, ycoord);

	// and write those coordinates to the screen
	cout << "We have taken the string and gotten the original coordintes back:\n";
	cout << xcoord << "\n";
	cout << ycoord << "\n";

	cout << "Now input your lower corner of the box: \n";
	int xlow, xhigh, ylow, yhigh;
	cin >> xlow;
	cin >> ylow;
	cout << "Now input your higher corner of the box: \n";
	cin >> xhigh;
	cin >> yhigh;
	
	char low[100];
	char high[100];
	GetBounds (low, high, xlow, ylow, xhigh, yhigh);
	cout << low << "\n";	
	cout << high << "\n";	
}
